package com.example.mq2sensor;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {
    // 可能的ADC文件路径（根据实际验证调整）
    private static final String[] ADC_PATHS = {
            "/sys/bus/iio/devices/iio:device0/in_voltage_pm7325_gpio2_adc_input"
    };

    private String activeAdcPath = null;
    private static final int DEFAULT_ADC_MAX = 65535; // 假设16位ADC，需校准
    private int adcMaxValue = DEFAULT_ADC_MAX;
    private static final int UPDATE_INTERVAL = 1000; // 1秒更新间隔

    // 传感器校准参数
    private double calibrationOffset = 0.0;
    private int lastRawValue = 0;

    // UI组件
    private TextView tvSmokeLevel;
    private ProgressBar pbSmoke;
    private TextView tvVoltage;
    private TextView tvRawValue;

    // 状态处理
    private final Handler handler = new Handler(Looper.getMainLooper());
    private Runnable sensorReader;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化UI组件
        tvSmokeLevel = findViewById(R.id.tv_smoke_level);
        pbSmoke = findViewById(R.id.pb_smoke);
        tvVoltage = findViewById(R.id.tv_voltage);
        tvRawValue = findViewById(R.id.tv_raw_value);

        // 初始化ADC路径
        detectAdcPath();

        // 初始化传感器读取任务
        initSensorReader();
    }

    private void initSensorReader() {
        sensorReader = new Runnable() {
            @Override
            public void run() {
                // 读取ADC原始值
                int rawValue = readAdcValue();
                lastRawValue = rawValue;

                // 处理无效数据
                if (rawValue < 0) {
                    updateUI("传感器未连接", 0, 0, 0);
                    handler.postDelayed(this, UPDATE_INTERVAL);
                    return;
                }

                // 计算真实电压（考虑2:1分压）
                double realVoltage = (rawValue * 3.3 * 2.0) / adcMaxValue;
                double calibratedVoltage = realVoltage - calibrationOffset;

                // 计算烟雾浓度
                double smokePpm = calculateSmokeConcentration(calibratedVoltage);
                int percent = (int) Math.min(100, Math.max(0, smokePpm / 10));

                // 更新UI
                updateUI("烟雾浓度：" + percent + " %", percent, calibratedVoltage, rawValue);

                // 检查警报状态
                checkAlarmStatus(percent);

                // 循环执行
                handler.postDelayed(this, UPDATE_INTERVAL);
            }
        };
    }

    /**
     * 检测可用的ADC路径
     */
    private boolean detectAdcPath() {
        for (String path : ADC_PATHS) {
            File file = new File(path);
            if (file.exists()) {
                try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
                    String value = reader.readLine();
                    if (value != null && !value.trim().isEmpty()) {
                        activeAdcPath = path;
                        Log.i("ADC", "检测到有效ADC路径: " + path);
                        return true;
                    }
                } catch (Exception e) {
                    Log.w("ADC", "路径验证失败: " + path);
                }
            }
        }
        Log.e("ADC", "未找到可用的ADC路径");
        return false;
    }

    private void updateUI(String text, int percent, double voltage, int rawValue) {
        runOnUiThread(() -> {
            tvSmokeLevel.setText(text);
            pbSmoke.setProgress(percent);
//            tvSmokeLevel.setText("50");
//            pbSmoke.setProgress(50); // 测试UI组件是否正常工作
            tvVoltage.setText(String.format("电压: %.2f V", voltage));
            tvRawValue.setText(String.format("原始值: %d", rawValue));
        });
    }

    private void checkAlarmStatus(int percent) {
        if (percent > 30) {
            runOnUiThread(() -> Toast.makeText(MainActivity.this, "警告：烟雾浓度过高！", Toast.LENGTH_SHORT).show());
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        handler.post(sensorReader); // 启动传感器读取
    }

    @Override
    protected void onPause() {
        super.onPause();
        handler.removeCallbacks(sensorReader); // 停止读取
    }

    /**
     * 读取ADC值
     */
    private int readAdcValue() {
        if (activeAdcPath == null && !detectAdcPath()) {
            return -1;
        }

        try (BufferedReader reader = new BufferedReader(new FileReader(activeAdcPath))) {
            String line = reader.readLine();
            int value = Integer.parseInt(line.trim());
            Log.d("ADC", String.format("路径[%s]读取值: %d", activeAdcPath, value));
            return value;
        } catch (Exception e) {
            Log.e("ADC", "读取失败: " + e.getMessage());
            return -1;
        }
    }

    /**
     * MQ2传感器校准公式（考虑2:1分压）
     */
    private double calculateSmokeConcentration(double voltage) {
        double V0 = 0.5 + calibrationOffset;  // 洁净空气中电压
        double K = 0.8;                      // 灵敏度系数

        double concentration = Math.pow(10, (voltage - V0) / K);
        return Math.min(100, concentration / 10);
    }

    /**
     * 校准传感器（在洁净空气中调用）
     */
    public void calibrateSensor() {
        int rawValue = readAdcValue();
        if (rawValue >= 0) {
            double currentVoltage = (rawValue * 3.3 * 2.0) / adcMaxValue;
            calibrationOffset = currentVoltage - 0.5; // 假设0.5V为洁净空气基准
            Toast.makeText(this, "传感器校准完成", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "无法校准：无有效数据", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 校准ADC量程（使用已知电压源调用）
     */
    public void calibrateAdcRange(double knownVoltage) {
        int rawValue = readAdcValue();
        if (rawValue > 0) {
            adcMaxValue = (int) ((rawValue * 3.3 * 2) / knownVoltage);
            Toast.makeText(this,
                    String.format("ADC量程校准完成: 最大值=%d", adcMaxValue),
                    Toast.LENGTH_SHORT).show();
        }
    }
}
